package xyz.labmem.main.application.controller.api.sys.menu;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import xyz.labmem.main.annotation.RoleValid;
import xyz.labmem.main.application.controller.api.sys.menu.response.MenuListResponse;
import xyz.labmem.main.application.controller.api.sys.menu.response.MenuTreeResponse;
import xyz.labmem.main.application.entity.sys.Menu;
import xyz.labmem.main.application.entity.sys.Role;
import xyz.labmem.main.application.mapper.sys.RoleMapper;
import xyz.labmem.main.enums.StateEnum;
import xyz.labmem.main.result.ResultUtil;
import xyz.labmem.main.result.ResultVo;
import xyz.labmem.main.sys.StaticVariable;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author ：刘天予
 * @date ：Created in 2020/5/8 11:07
 * @description：菜单
 */
@RestController
@Api(tags = "后台菜单API")
@RequestMapping("/admin/menu/api")
public class MenuApi extends StaticVariable {

    private final RoleMapper roleMapper;

    public MenuApi(RoleMapper roleMapper) {
        this.roleMapper = roleMapper;
    }

    @GetMapping("/tree")
    @RoleValid
    @ApiOperation("三级菜单树")
    public Object menuTree() {
        List<MenuTreeResponse> data = new ArrayList<>();
        List<Menu> menups = new Menu()
                .selectList(
                        new LambdaQueryWrapper<Menu>()
                                .isNull(Menu::getPid)
                                .eq(Menu::getState, StateEnum.ON)
                                .and(l -> l.like(Menu::getRoleList, "\"" + this.getUser().getRole() + "\"")
                                        .or()
                                        .isNull(Menu::getRoleList)
                                        .or()
                                        .eq(Menu::getRoleList, "")
                                )
                                .orderByAsc(Menu::getSort)
                );
        menups.forEach(p -> data.addAll(childMenu(p)));

        return data;
    }

    /**
     * @return
     */
    @PostMapping("/list")
    @RoleValid
    @ApiOperation("菜单树列表")
    public ResultVo menuList(@RequestBody Map<String, String> map) {
        List<MenuListResponse> data = new ArrayList<>();
        LambdaQueryWrapper<Menu> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        String title = map.get("title");
        if (StrUtil.isNotEmpty(title)) {
            lambdaQueryWrapper.like(Menu::getTitle, title);
        }
        lambdaQueryWrapper.ne(Menu::getState, StateEnum.DEL);
        lambdaQueryWrapper.orderByAsc(Menu::getSort);
        List<Menu> menups = new Menu().selectList(lambdaQueryWrapper);
        menups.forEach(m -> {
            MenuListResponse menuListResponse = new MenuListResponse(m);
            if (StrUtil.isNotEmpty(m.getRoleList())) {
                JSONArray RoleList = JSONArray.parseArray(m.getRoleList());
                List<String> list = RoleList.toJavaList(String.class);
                StringBuilder RoleString = new StringBuilder();
                StringBuilder RoleId = new StringBuilder();
                new Role().selectList(new LambdaQueryWrapper<Role>().in(Role::getRoleEnum, list)).forEach(r -> {
                    RoleString.append(r.getRoleName()).append(",");
                    RoleId.append(r.getId()).append(",");
                });
                menuListResponse.setRoleString(RoleString.toString());
                menuListResponse.setRoleList(RoleId.toString());
            }
            data.add(menuListResponse);
        });
        return ResultUtil.success(data);
    }

    /**
     * @return
     */
    @PostMapping("/addOrUpdate")
    @RoleValid
    @ApiOperation("增加或修改菜单")
    public ResultVo menuAddOrUpdate(@RequestBody Menu menu) {
        if (menu.getRoleList() != null) {
            JSONArray roleEnumList = new JSONArray();
            JSONArray RoleList = JSONArray.parseArray(menu.getRoleList());
            List<String> list = RoleList.toJavaList(String.class);
            roleMapper.selectBatchIds(list).forEach(r -> roleEnumList.add(r.getRoleEnum()));
            menu.setRoleList(roleEnumList.toJSONString());
        } else {
            menu.setRoleList("");
        }
        if (menu.insertOrUpdate())
            return ResultUtil.success();
        else
            return ResultUtil.failed();
    }


    private List<MenuTreeResponse> childMenu(Menu p) {
        List<MenuTreeResponse> menups = new ArrayList<>();
        if (p.getType() == 1)
            menups.add(new MenuTreeResponse(p));
        else {
            List<MenuTreeResponse> childs = new ArrayList<>();
            List<Menu> menus = new Menu().selectList(
                    new LambdaQueryWrapper<Menu>()
                            .eq(Menu::getPid, p.getId())
                            .eq(Menu::getState, StateEnum.ON)
                            .and(l -> l.like(Menu::getRoleList, "\"" + this.getUser().getRole() + "\"")
                                    .or()
                                    .isNull(Menu::getRoleList)
                                    .or()
                                    .eq(Menu::getRoleList, "")
                            )
                            .orderByAsc(Menu::getSort)
            );
            menus.forEach(c -> childs.addAll(childMenu(c)));
            MenuTreeResponse treeResponse = new MenuTreeResponse(p);
            treeResponse.setChildren(childs);
            menups.add(treeResponse);
        }
        return menups;
    }

}
